package other;

import java.awt.image.BufferedImage;
import java.io.File;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;

import org.bytedeco.javacv.*;
import org.bytedeco.javacv.FrameGrabber.ImageMode;
import org.bytedeco.javacv.OpenCVFrameConverter.ToIplImage;
import org.bytedeco.javacpp.*;
import org.bytedeco.javacpp.opencv_core.CvMemStorage;
import org.bytedeco.javacpp.opencv_core.CvPoint;
import org.bytedeco.javacpp.opencv_core.IplImage;
import org.bytedeco.javacpp.opencv_imgproc.CvFont;
import org.bytedeco.javacpp.opencv_objdetect.CvHaarClassifierCascade;
import org.bytedeco.javacpp.indexer.*;
import static org.bytedeco.javacpp.opencv_core.*;
import static org.bytedeco.javacpp.opencv_imgproc.*;
import static org.bytedeco.javacpp.opencv_calib3d.*;
import static org.bytedeco.javacpp.opencv_objdetect.*;

public class JavaCVDemo {
	private String classifierName = "./haarcascade_frontalface_alt.xml";
	private Java2DFrameConverter frameConverter;
	private IplImage grayImage;
	public IplImage grabbedImage;
	private CvMemStorage storage;
	private CvPoint hatPoints;
	private ToIplImage converter;
	private CanvasFrame frame;
	private CvHaarClassifierCascade classifier;
	private OpenCVFrameGrabber grabber;
	private long start;
	private long end;
	public BufferedImage buffer;
	
	
	public void init()throws Exception {
		Loader.load(opencv_objdetect.class);

		
		classifier = new CvHaarClassifierCascade(cvLoad(classifierName));
		if (classifier.isNull()) {
			System.err.println("Error loading classifier file \"" + classifierName + "\".");
			System.exit(1);
		}
		grabber = OpenCVFrameGrabber.createDefault(0);
//		grabber.setImageHeight(200);
//		grabber.setImageWidth(200);
		grabber.start();

		converter = new OpenCVFrameConverter.ToIplImage();
		
		grabbedImage = converter.convert(grabber.grab());
		int width = grabbedImage.width();
		int height = grabbedImage.height();
		grayImage = IplImage.create(width, height, IPL_DEPTH_8U, 1);
		storage = CvMemStorage.create();

		frame = new CanvasFrame("Some Title", CanvasFrame.getDefaultGamma() / grabber.getGamma());

		hatPoints = new CvPoint(3);
		start = System.currentTimeMillis();
		end = start;
		CvFont font = new CvFont();
		cvInitFont(font, CV_FONT_HERSHEY_COMPLEX_SMALL, 0.8, 0.8, 0, 1, 8);

		frameConverter = new Java2DFrameConverter();
	}
	public void loop()throws Exception{
		while (frame.isVisible() && (grabbedImage = converter.convert(grabber.grab())) != null) {
			cvClearMemStorage(storage);
			cvCvtColor(grabbedImage, grayImage, CV_BGR2GRAY);
			CvSeq faces = cvHaarDetectObjects(grayImage, classifier, storage, 1.1, 3, CV_HAAR_FIND_BIGGEST_OBJECT);
			int total = faces.total();
			for (int i = 0; i < total; i++) {
				CvRect r = new CvRect(cvGetSeqElem(faces, i));
				int x = r.x(), y = r.y(), w = r.width(), h = r.height();
				cvRectangle(grabbedImage, cvPoint(x, y), cvPoint(x + w, y + h), CvScalar.RED, 2, CV_AA, 0);

				// call position() before.
				hatPoints.position(0).x(x - w / 10).y(y - h / 10);
				hatPoints.position(1).x(x + w * 11 / 10).y(y - h / 10);
				hatPoints.position(2).x(x + w / 2).y(y - h / 2);
				cvFillConvexPoly(grabbedImage, hatPoints.position(0), 3, CvScalar.GREEN, CV_AA, 0);
				r.close();
			}
			buffer = frameConverter.convert(converter.convert(grabbedImage));
			end = System.currentTimeMillis();
			buffer.getGraphics().drawString(String.valueOf(1000 / (end - start)), 100, 100);
			start = end;
			frame.showImage(buffer);
		}
		frame.dispose();
		grabber.stop();
	}

	public static void main(String[] args) throws Exception {
		JavaCVDemo cvDemo=new JavaCVDemo();
		cvDemo.init();
		cvDemo.loop();
	}
}